/******
    ************************************************************************
    ******
    ** @project : XDrive_Step
    ** @brief   : Stepper motor with multi-function interface and closed loop function. 
    ** @brief   : 具有多功能接口和闭环功能的步进电机
    ** @author  : unlir (知不知啊)
    ** @contacts: QQ.1354077136
    ******
    ** @address : https://github.com/unlir/XDrive
    ******
    ************************************************************************
    ******
    ** {Stepper motor with multi-function interface and closed loop function.}
    ** Copyright (c) {2020}  {unlir(知不知啊)}
    ** 
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU General Public License as published by
    ** the Free Software Foundation, either version 3 of the License, or
    ** (at your option) any later version.
    ** 
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU General Public License for more details.
    ** 
    ** You should have received a copy of the GNU General Public License
    ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ******
    ************************************************************************
******/

/*****
  ** @file     : loop.c/h and loop_it.c
  ** @brief    : MCU系工程主框架
  ** @versions : newest
    ** @time     : newest
  ** @reviser  : unli (WuHu China)
    ** @explain  : null
*****/

//Application_User_Core
// #include "usart.h"

//Base_Drivers
#include "mt6816.h"

//Kernel
#include "loop.h"

//Control
#include "signal_port.h"
#include "motor_control.h"
#include "encode_cali.h"
#include "power_detect.h"
#include "hw_elec.h"

//Debug
#include "button.h"

//核心中断标志数据
bool systick_20khz_flag = false;    //20KHz系统时钟标志
uint8_t lit_1ms_divider = 0;            //副时钟分频器(1ms)

bool cricle_open_switch = CIRCLE;

struct Loop_IT_Typedef{
    //中断计数器
    uint32_t    systick_count;
    uint32_t    exti7_count;
    uint32_t    time2_count;
    uint32_t    dma1_ch4_count;
    uint32_t    dma1_ch5_count;
    uint32_t    uart1_count;
}loop_it;

/**
* @brief  系统计时器修改为20KHz
  * @param  NULL
  * @retval NULL
**/
void LoopIT_SysTick_20KHz(void)
{
    systick_20khz_flag = true;
    SysTick_Config(SystemCoreClock / 20000U);    //更新为20K中断
}

/**
  * @brief This function handles System tick timer.
    * 启动初期由自动初始化的SysTick为1KHz
    * 由REIN库接管后修改的SysTick为20KHz
**/
void SysTick_Handler(void)
{
    if(systick_20khz_flag){
        //编码器数据采集
        REIN_MT6816_Get_AngleData();
        //电源数据采集
        // Power_Detection_Run();

        //运动控制
        if(encode_cali.trigger)    Calibration_Interrupt_Callback();    //校准器中断回调
        else                       Motor_Control_Callback();            //控制器任务回调

        //1ms分频
        lit_1ms_divider++;
        if(lit_1ms_divider >= 20){
            lit_1ms_divider  = 0;
            loop_second_base_1ms();        //副时钟1ms时钟
            delay_decrement();    //提供1ms中断调用, 暂时未使用延时
        }
    }
    else{
        delay_decrement();    //提供1ms中断调用
    }

    loop_it.systick_count++;
}

/**
  * @brief  中断优先级覆盖
  * @param  NULL
  * @retval NULL
**/
void LoopIT_Priority_Overlay(void)
{
    /**********中断优先级**********/
    //中断优先级规则
    //0：输入信号关键中断
    //1：传感器关键中断
    //2：任务中断
    //3: 通讯中断

    //中断号                                                                                优先级            中断源                                                用途
    nvic_irq_enable(SIGNAL_COUNT_DIR_Get_IRQn, 0U, 0U);        //外部中断(SIGNAL_COUNT_DIR)        获取SIGNAL_COUNT计数器方向
    nvic_irq_enable(SIGNAL_PWM_Get_IRQn,                0u,    0u);        //定时器捕获(SIGNAL_PWM_PWM)        获取SIGNAL_PWM两个边沿计数值
    NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 0));        //系统定时器                                        核心时钟
}

int count = 100;
/**
  * @brief EXTI9_5_IRQHandler
**/
void EXTI5_9_IRQHandler(void)
{
    //PA7中断
    if(exti_interrupt_flag_get(EXTI_7) != 0x00u){
        exti_interrupt_flag_clear(EXTI_7);
        Signal_Count_Dir_Res();        //信号COUNT_DIR中断
    }
    loop_it.exti7_count++;
}

/**
  * @brief EXTI15_10_IRQHandler
**/
void EXTI10_15_IRQHandler(void)
{
  if(exti_interrupt_flag_get(EXTI_15) != RESET){
    exti_interrupt_flag_clear(EXTI_15);
    step_num = 0;
    motor_control.soft_brake = true;
  }
}

/**
  * @brief TIMER2_IRQHandler
**/
void TIMER2_IRQHandler(void)
{
    //TIM2的中断标志清除由PWM处理函数识别并清除
    Signal_PWM_TIM_Callback();    //SIGNAL_PWM采集中断回调

    loop_it.time2_count++;
}
